import bomService from "@/api/services/base/bomService";
import workOrderService from "@/api/services/mes/workOrderService";
import { TableToolbar } from "@/components/grid/TableToolbar";
import useDictionary from "@/hooks/system/useDictionary";
import MultiMaterialSelect from "@/pages/components/selector/MultiMaterialSelect";
import { Button, Input, InputNumber, Select } from "antd";
import Table, { type ColumnsType } from "antd/es/table";
import {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useMemo,
  useState,
} from "react";
import { toast } from "sonner";
import type { MesWorkOrderBomItem } from "./entity";
import type { Material } from "@/pages/base/material/entity";

interface MesWorkOrderBomItemProps {
  parentId?: React.Key;
  formValues: Record<string, any>;
  onListChange: (list: MesWorkOrderBomItem[]) => void;
}

export interface MesWorkOrderBomItemHandles {
  getAddList: () => MesWorkOrderBomItem[];
  getUpdateList: () => MesWorkOrderBomItem[];
  getDeleteIds: () => React.Key[];
}

const MesWorkOrderBomItemPage = forwardRef<
  MesWorkOrderBomItemHandles,
  MesWorkOrderBomItemProps
>(({ parentId, formValues, onListChange }, ref) => {
  const [loading, setLoading] = useState(false);
  const [list, setList] = useState<MesWorkOrderBomItem[]>([]);
  const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
  // 添加一个状态来跟踪临时ID
  const [tempIds, setTempIds] = useState<React.Key[]>([]);
  const [addList, setAddList] = useState<MesWorkOrderBomItem[]>([]);
  const [updateList, setUpdateList] = useState<MesWorkOrderBomItem[]>([]);
  const [deleteIds, setDeleteIds] = useState<React.Key[]>([]);

  const [selectVisiable, setSelectVisiable] = useState(false);

  const isCriticalOptions = useDictionary("system_true_false");

  useImperativeHandle(
    ref,
    () => ({
      getAddList: () => addList,
      getUpdateList: () => updateList,
      getDeleteIds: () => deleteIds,
    }),
    [addList, updateList, deleteIds]
  );

  useEffect(() => {
    const newAddList = list.filter(
      (item) => item.id && tempIds.includes(item.id)
    );
    setAddList(newAddList);
    const updateList = list.filter(
      (item) => item.id && !tempIds.includes(item.id)
    );
    setUpdateList(updateList);

    onListChange(list);
  }, [list, tempIds]);

  const [tableSize, setTableSize] = useState<"large" | "middle" | "small">(
    "middle"
  );

  //动态设置表格高度
  const [tableScrollY, setTableScrollY] = useState(0);
  const PAGE_OFFSET_HEIGHT = 403;
  const updateTableHeight = () => {
    const newHeight = window.innerHeight - PAGE_OFFSET_HEIGHT;
    setTableScrollY(newHeight > 200 ? newHeight : 200); // 保证最小高度
  };

  // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
  useEffect(() => {
    updateTableHeight(); // 初始化
    window.addEventListener("resize", updateTableHeight);
    return () => window.removeEventListener("resize", updateTableHeight);
  }, []);

  //表格列定义
  const columns: ColumnsType<MesWorkOrderBomItem> = [
    {
      title: "物料编码",
      width: 120,
      key: "materialCode",
      dataIndex: "materialCode",
    },
    {
      title: "物料名称",
      width: 120,
      key: "materialName",
      dataIndex: "materialName",
    },
    {
      title: "物料规格",
      width: 120,
      key: "materialSpec",
      dataIndex: "materialSpec",
    },
    {
      title: "每件用量",
      width: 120,
      key: "qty",
      dataIndex: "qty",
      render: (text, record) => (
        <InputNumber
          value={text}
          onChange={(e) => handleFieldChange(record.id, "qty", e.target.value)}
        />
      ),
    },
    {
      title: "损耗率（%）",
      width: 120,
      key: "lossRate",
      dataIndex: "lossRate",
      render: (text, record) => (
        <InputNumber
          value={text}
          onChange={(e) =>
            handleFieldChange(record.id, "lossRate", e.target.value)
          }
        />
      ),
    },
    {
      title: "计划总用量",
      width: 120,
      key: "totalQty",
      dataIndex: "totalQty",
      render: (text) => <span>{text}</span>,
    },
    {
      title: "是否关键物料",
      width: 120,
      key: "isCritical",
      dataIndex: "isCritical",
      render: (text, record) => (
        <Select
          options={isCriticalOptions}
          value={text}
          onChange={(e) =>
            handleFieldChange(record.id, "totalQty", e.target.value)
          }
        />
      ),
    },
    {
      title: "备注",
      width: 120,
      key: "remark",
      dataIndex: "remark",
      render: (text, record) => (
        <Input
          value={text}
          onChange={(e) =>
            handleFieldChange(record.id, "remark", e.target.value)
          }
        />
      ),
    },
  ];

  const [selectedValues, setSelectedValues] = useState<string[]>(() =>
    columns
      .filter((col) => col.key !== "operation")
      .map((col) => (col.key ? String(col.key) : ""))
  );

  // 处理字段变更
  const handleFieldChange = (id: string, field: string, value: any) => {
    let inputValue: any = null;

    // 类型转换逻辑
    if (typeof value === "boolean") {
      inputValue = value ? 1 : 0;
    } else if (value instanceof Date) {
      inputValue = dayjs(value).format("YYYY-MM-DD");
    } else {
      inputValue = value;
    }

    setList((prevData) =>
      prevData.map((item) => {
        if (item.id !== id) return item;

        const updatedItem = {
          ...item,
          [field]: inputValue,
        };

        // 👇 加入联动计算逻辑
        if (field === "qty" || field === "lossRate") {
          const qty = Number.parseFloat(
            field === "qty" ? inputValue : updatedItem.qty || 0
          );
          const lossRate = Number.parseFloat(
            field === "lossRate" ? inputValue : updatedItem.lossRate || 0
          );
          const planQty = formValues?.planQty || 0;

          const totalQty =
            qty * planQty * (1 + (lossRate ? lossRate / 100 : 0));
          updatedItem.totalQty = Number.isFinite(totalQty)
            ? Number(totalQty.toFixed(4))
            : 0;
        }

        return updatedItem;
      })
    );
  };

  // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
  const filteredColumns = useMemo(() => {
    return [
      ...columns.filter(
        (col) =>
          selectedValues.includes(String(col.key)) || col.key === "operation"
      ),
    ].sort((a, b) => {
      const originalIndex = columns.findIndex((c) => c.key === a.key);
      const targetIndex = columns.findIndex((c) => c.key === b.key);
      return originalIndex - targetIndex;
    });
  }, [selectedValues]);

  //加载表格数据
  const fetchList = () => {
    if (!parentId) return;

    setLoading(true);
    workOrderService
      .getitems(parentId)
      .then((res) => {
        setList(res);
        onListChange(res);
      })
      .catch((error) => {
        console.log(error);
        toast.error("获取数据失败！", error);
      })
      .finally(() => {
        setLoading(false);
      });
  };

  // biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
  useEffect(() => {
    if (parentId) {
      fetchList();z``
    } else {
      // 初始化时清空状态
      setList([]);
      setSelectedRowKeys([]);
      setTempIds([]);
      setAddList([]);
      setUpdateList([]);
      setDeleteIds([]);
    }
  }, [parentId]);

  useEffect(() => {
    const newAddList = list.filter(
      (item) => item.id && tempIds.includes(item.id)
    );
    setAddList(newAddList);
    const updateList = list.filter(
      (item) => item.id && !tempIds.includes(item.id)
    );
    setUpdateList(updateList);
  }, [list, tempIds]);

  //检验是否输入值
  const validatePartsBeforeAdd = (): boolean => {
    for (const detail of list) {
      if (!detail.workOrderId) {
        toast.error("生产工单ID");
        return false;
      }
      if (!detail.materialId) {
        toast.error("BOM物料ID");
        return false;
      }
    }
    return true;
  };

  //加载产品BOM信息
  const loadProductBom = () => {
    if (!formValues?.productId) {
      toast.error("请选择产品");
      return;
    }

     setLoading(true);
    bomService
      .getBomByProduct(formValues.productId)
      .then((res) => {
        // 先获取已存在的 materialId 列表
        const existItemIds = list.map((item) => item.materialId);

        const planQty = formValues.planQty;
        const newBomItemList: MesWorkOrderBomItem[] = res
          .filter((item) => !existItemIds.includes(item.materialId))
          .map((item) => ({
            id: item.id, // 使用临时ID
            workOrderId: parentId,
            materialId: item.materialId,
            materialCode: item.materialCode,
            materialName: item.materialName,
            materialSpec: item.materialSpec,
            qty: item.qty,
            lossRate: item.lossRate,
            totalQty:
              item.qty *
              planQty *
              (1 + (item.lossRate ? item.lossRate / 100 : 0)),
            isCritical: "0",
          }));

        setList((prevList) => [...prevList, ...newBomItemList]);
        // 添加到临时ID列表
        const newTempIds = newBomItemList.map((item) => item.id);
        setTempIds((prev) => [...prev, ...newTempIds]);
      })
      .catch((error) => {
        console.log(error);
        toast.error(error.message);
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const handleSelect = (selectedMaterials: Material[]) => {
    // 先获取已存在的 materialId 列表
    const existMaterialIds = list.map((item) => item.materialId);

    const planQty = formValues?.planQty || 0;
    // 只添加不存在于 list 中的 material
    const newMaterialList: MesWorkOrderBomItem[] = selectedMaterials
      .filter((material) => !existMaterialIds.includes(material.id))
      .map((material) => ({
        id: material.id, // 使用临时ID
        orkOrderId: parentId,
        materialId: material.id,
        materialCode: material.materialCode,
        materialName: material.materialName,
        materialSpec: material.spec,
        qty: 1,
        lossRate: 0,
        totalQty: planQty,
        isCritical: "0",
      }));

    setList((prevList) => [...prevList, ...newMaterialList]);
    // 添加到临时ID列表
    const newTempIds = newMaterialList.map((item) => item.id);
    setTempIds((prev) => [...prev, ...newTempIds]);
    setSelectVisiable(false);
  };

  const handleAdd = () => {
    if (!validatePartsBeforeAdd()) {
      return; // 校验未通过，不执行新增
    }

    setSelectVisiable(true);
  };

  // 在删除方法中修改判断逻辑
  const handleDelete = () => {
    // 如果没有选中行，直接返回
    if (selectedRowKeys.length === 0) {
      return;
    }

    // 更新删除ID列表
    const newDeleteIds = [...deleteIds];

    // 将已有ID但不在deleteIds中的ID添加到deleteIds
    for (const key of selectedRowKeys) {
      const item = list.find((item) => item.id === key);
      if (item?.id && !tempIds.includes(item.id)) {
        // 如果不在临时ID列表中，则添加到删除列表
        if (!newDeleteIds.includes(item.id)) {
          newDeleteIds.push(item.id);
        }
      }
    }

    // 更新deleteIds状态
    setDeleteIds(newDeleteIds);

    // 从列表中移除选中的行
    setList((prevList) =>
      prevList.filter((item) => !selectedRowKeys.includes(item.id))
    );
    // 从tempIds中移除被删除的临时ID
    setTempIds((prevTempIds) =>
      prevTempIds.filter((id) => !selectedRowKeys.includes(id))
    );
    // 清空选中状态
    setSelectedRowKeys([]);
  };

  return (
    <>
      <div className="flex justify-between mb-4">
        <div className="flex gap-2">
          <Button type="primary" onClick={loadProductBom}>
            加载产品BOM
          </Button>
          <Button type="primary" onClick={handleAdd}>
            新增
          </Button>
          <Button
            danger
            disabled={selectedRowKeys.length === 0}
            onClick={handleDelete}
          >
            删除
          </Button>
        </div>
        <TableToolbar
          onRefresh={() => fetchList()}
          onSizeChange={setTableSize}
          columns={columns}
          selectedValues={selectedValues}
          onColumnChange={setSelectedValues}
        />
      </div>
      <Table
        rowKey="id"
        size={tableSize}
        scroll={{ x: "max-content", y: tableScrollY }}
        loading={loading}
        pagination={false}
        columns={filteredColumns}
        dataSource={list}
        rowSelection={{
          type: "checkbox",
          selectedRowKeys: selectedRowKeys,
          onChange: (selectedKeys) => {
            setSelectedRowKeys(selectedKeys as React.Key[]);
          },
        }}
      />

        <MultiMaterialSelect
          open={selectVisiable}
          onCancel={() => setSelectVisiable(false)}
          onOk={(item) => handleSelect(item)}
        />
    </>
  );
});

export default MesWorkOrderBomItemPage;
